---
import NodeGraphNew from './NodeGraph';
import { getNodesAndEdges as getNodesAndEdgesForService } from '@utils/node-graphs/services-node-graph';
import {
  getNodesAndEdgesForCommands,
  getNodesAndEdgesForEvents,
  getNodesAndEdgesForQueries,
} from '@utils/node-graphs/message-node-graph';
import {
  getNodesAndEdges as getNodesAndEdgesForDomain,
  getNodesAndEdgesForDomainContextMap,
} from '@utils/node-graphs/domains-node-graph';
import { getNodesAndEdges as getNodesAndEdgesForDomainEntityMap } from '@utils/node-graphs/domain-entity-map';
import { getDomainsCanvasData } from '@utils/node-graphs/domains-canvas';
import { getNodesAndEdges as getNodesAndEdgesForFlows } from '@utils/node-graphs/flows-node-graph';
import { buildUrl } from '@utils/url-builder';
import { getVersionFromCollection } from '@utils/collections/versions';
import { pageDataLoader } from '@utils/page-loaders/page-data-loader';
import { getNodesAndEdges as getNodesAndEdgesForContainer } from '@utils/node-graphs/container-node-graph';
import config from '@config';

interface Props {
  id: string;
  collection: string;
  title?: string;
  version: string;
  mode: 'full' | 'simple';
  linkTo?: 'docs' | 'visualiser';
  href?: {
    label: string;
    url: string;
  };
  linksToVisualiser?: boolean;
  showSearch?: boolean;
  showLegend?: boolean;
  zoomOnScroll?: boolean;
}

const {
  id,
  collection,
  title,
  mode = 'simple',
  linkTo = 'docs',
  version,
  href,
  linksToVisualiser,
  showSearch = true,
  showLegend = true,
  zoomOnScroll = false,
} = Astro.props;

let nodes = [],
  edges = [];

const getNodesAndEdgesFunctions = {
  services: getNodesAndEdgesForService,
  events: getNodesAndEdgesForEvents,
  commands: getNodesAndEdgesForCommands,
  queries: getNodesAndEdgesForQueries,
  domains: getNodesAndEdgesForDomain,
  flows: getNodesAndEdgesForFlows,
  containers: getNodesAndEdgesForContainer,
};

let links: { label: string; url: string }[] = [];

if (collection in getNodesAndEdgesFunctions) {
  const { nodes: fetchedNodes, edges: fetchedEdges } = await getNodesAndEdgesFunctions[
    collection as keyof typeof getNodesAndEdgesFunctions
  ]({
    id,
    version,
    mode,
    channelRenderMode: config.visualiser?.channels?.renderMode === 'single' ? 'single' : 'flat',
  });

  nodes = fetchedNodes;
  edges = fetchedEdges;

  if (mode === 'full') {
    // Try and get the list of versions for the rendered item
    try {
      const allItems = await pageDataLoader[collection as keyof typeof pageDataLoader]();
      const versions = getVersionFromCollection(allItems, id, version);

      const item = versions[0];
      const listOfVersions = item.data.versions || [];

      // Order by version
      listOfVersions.sort((a, b) => b.localeCompare(a));

      if (listOfVersions.length > 1) {
        links = listOfVersions.map((version) => ({
          label: `${item.data.name} v${version}`,
          url: buildUrl(`/visualiser/${collection}/${id}/${version}`),
          selected: version === version,
        }));
      }
    } catch (error) {
      links = [];
    }
  }
}

if (collection === 'domain-context-map') {
  const { nodes: fetchedNodes, edges: fetchedEdges } = await getNodesAndEdgesForDomainContextMap({});
  nodes = fetchedNodes;
  edges = fetchedEdges;
}

if (collection === 'domains-canvas') {
  const { domainNodes, messageNodes, edges: fetchedEdges } = await getDomainsCanvasData();
  nodes = [...domainNodes, ...messageNodes];
  edges = fetchedEdges;
}

if (collection === 'domains-entities') {
  const { nodes: fetchedNodes, edges: fetchedEdges } = await getNodesAndEdgesForDomainEntityMap({
    id,
    version,
  });
  nodes = fetchedNodes;
  edges = fetchedEdges;
}

if (collection === 'services-containers') {
  const { nodes: fetchedNodes, edges: fetchedEdges } = await getNodesAndEdgesForService({
    id,
    version,
    renderMessages: false,
    mode: 'full',
  });
  nodes = fetchedNodes;
  edges = fetchedEdges;
}
---

<div>
  <NodeGraphNew
    id={id}
    nodes={nodes}
    edges={edges}
    title={title}
    hrefLabel={href?.label}
    href={href?.url}
    linkTo={linkTo}
    client:only="react"
    linksToVisualiser={linksToVisualiser}
    links={links}
    mode={mode}
    showSearch={showSearch}
    includeKey={showLegend}
    zoomOnScroll={zoomOnScroll}
  />
</div>

<style is:global>
  .react-flow__attribution {
    display: none;
  }
</style>
